package org.ccay.core.ioc;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Locale;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;


/**
 * Spring ApplicationContext的代理类。作用与 ApplicationContext 一致，用于从容器获取对象。
 * 此类的示例通过 Ccay 类获取, @see {@link Ccay}
 * 
 */
public class CcayApplicationContext implements ApplicationContext {
	
	/** 
	 * 所代理的Spring ApplicationContext 
	 */
	private ApplicationContext delegator;
	
	/**
	 * 获取原始上下文，不推荐使用此方法
	 */
	public ApplicationContext getOriginalContext(){
		return delegator;
	}
	
	/**
	 * 构造函数
	 * 
	 * @param delegator 所代理的Spring ApplicationContext
	 */
	public CcayApplicationContext(ApplicationContext delegator) {
		this.delegator = delegator;
	}

	public Environment getEnvironment() {
		return delegator.getEnvironment();
	}

	public boolean containsBeanDefinition(String arg0) {
		return delegator.containsBeanDefinition(arg0);
	}

	public <A extends Annotation> A findAnnotationOnBean(String arg0,
			Class<A> arg1) {
		return delegator.findAnnotationOnBean(arg0, arg1);
	}

	public int getBeanDefinitionCount() {
		return delegator.getBeanDefinitionCount();
	}

	public String[] getBeanDefinitionNames() {
		return delegator.getBeanDefinitionNames();
	}

	public String[] getBeanNamesForType(Class<?> arg0) {
		return delegator.getBeanNamesForType(arg0);
	}

	public String[] getBeanNamesForType(Class<?> arg0, boolean arg1,
			boolean arg2) {
		return delegator.getBeanNamesForType(arg0, arg1, arg2);
	}

	public <T> Map<String, T> getBeansOfType(Class<T> arg0)
			throws CcayBeansException {
		return delegator.getBeansOfType(arg0);
	}

	public <T> Map<String, T> getBeansOfType(Class<T> arg0, boolean arg1,
			boolean arg2) throws CcayBeansException {
		return delegator.getBeansOfType(arg0, arg1, arg2);
	}

	public Map<String, Object> getBeansWithAnnotation(
			Class<? extends Annotation> arg0) throws CcayBeansException {
		return delegator.getBeansWithAnnotation(arg0);
	}

	public boolean containsBean(String arg0) {
		return delegator.containsBean(arg0);
	}

	public String[] getAliases(String arg0) {
		return delegator.getAliases(arg0);
	}

	public Object getBean(String arg0) throws CcayBeansException {
		try {
			return delegator.getBean(arg0);
		} catch (BeansException ex) {
			throw new CcayBeansException("ccay.core.00040001", ex);
		}
	}

	public <T> T getBean(String arg0, Class<T> arg1) throws CcayBeansException {
		try {
			return delegator.getBean(arg0, arg1);
		} catch (BeansException ex) {
			throw new CcayBeansException("ccay.core.00040001", ex);
		}
	}

	public Object getBean(String arg0, Object... arg1) throws CcayBeansException {
		try {
			return delegator.getBean(arg0, arg1);
		} catch (BeansException ex) {
			throw new CcayBeansException("ccay.core.00040001", ex);
		}
	}

	public Class<?> getType(String arg0) throws NoSuchBeanDefinitionException {
		return delegator.getType(arg0);
	}
	
	public boolean isPrototype(String arg0)
			throws NoSuchBeanDefinitionException {
		return delegator.isPrototype(arg0);
	}

	public boolean isSingleton(String arg0)
			throws NoSuchBeanDefinitionException {
		return delegator.isSingleton(arg0);
	}

	public boolean isTypeMatch(String arg0, Class<?> arg1)
			throws NoSuchBeanDefinitionException {
		return delegator.isTypeMatch(arg0, arg1);
	}

	public boolean containsLocalBean(String arg0) {
		return delegator.containsLocalBean(arg0);
	}

	public BeanFactory getParentBeanFactory() {
		return delegator.getParentBeanFactory();
	}

	public String getMessage(MessageSourceResolvable arg0, Locale arg1)
			throws NoSuchMessageException {
		return delegator.getMessage(arg0, arg1);
	}

	public String getMessage(String arg0, Object[] arg1, Locale arg2)
			throws NoSuchMessageException {
		return delegator.getMessage(arg0, arg1, arg2);
	}

	public String getMessage(String arg0, Object[] arg1, String arg2,
			Locale arg3) {
		return delegator.getMessage(arg0, arg1, arg2, arg3);
	}

	public void publishEvent(ApplicationEvent arg0) {
		delegator.publishEvent(arg0);
	}

	public Resource[] getResources(String arg0) throws IOException {
		return delegator.getResources(arg0);
	}

	public ClassLoader getClassLoader() {
		return delegator.getClassLoader();
	}

	public Resource getResource(String arg0) {
		return delegator.getResource(arg0);
	}

	public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
			throws IllegalStateException {
		return delegator.getAutowireCapableBeanFactory();
	}

	public String getDisplayName() {
		return delegator.getDisplayName();
	}

	public String getId() {
		return delegator.getId();
	}

	public ApplicationContext getParent() {
		return delegator.getParent();
	}

	public long getStartupDate() {
		return delegator.getStartupDate();
	}
	
	public String[] getBeanNamesForType(ResolvableType type) {
		return delegator.getBeanNamesForType(type);
	}
	
	public String[] getBeanNamesForAnnotation(
			Class<? extends Annotation> annotationType) {
		return delegator.getBeanNamesForAnnotation(annotationType);
	}
	
	public <T> T getBean(Class<T> requiredType, Object... args)
			throws CcayBeansException {
		return delegator.getBean(requiredType, args);
	}
	
	public boolean isTypeMatch(String name, ResolvableType typeToMatch)
			throws NoSuchBeanDefinitionException {
		return delegator.isTypeMatch(name, typeToMatch);
	}

	public void publishEvent(Object arg0) {
		delegator.publishEvent(arg0);
	}

	public String getApplicationName() {
		return delegator.getApplicationName();
	}

	public <T> T getBean(Class<T> arg0) throws CcayBeansException {
		return delegator.getBean(arg0);
	}

}
